/**
  ******************************************************************************
  * @file    commom.c
  * @author  Dragon.Chen
  * @version V1.0.0
  * @date    07-10-2020
  * @brief   对常用功能封装的函数库(这些函数无法划分到某个具体函数库的头文件中)
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2020 上海今中网络科技有限公司 </center></h2>
  ******************************************************************************
  */

#include "common.h"

/*
 * @brief  程序后台化
 * @param  NULL
 * @retval 成功返回0  失败-1
 */
int daemonize()
{
    int                 i;
    pid_t               pid;
    struct rlimit       rl;
    struct sigaction    sa;

    umask(0);
    if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
        return -1;
    if ((pid = fork()) < 0)
        return -1;
    else if (pid != 0)
        exit(0);
    setsid();

    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGHUP, &sa, NULL) < 0)
        return -1;
    if ((pid = fork()) < 0)
        return -1;
    else if (pid != 0)
        exit(0);

    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for (i=0; i<rl.rlim_max; i++)
        close(i);

    open("/dev/null", O_RDWR);
    dup(0);
    dup(0);

    return 0;
}

///**
//  * @brief  计算文件的大小
//  * @param  arg1：文件名
//  * @retval 文件大小
//  */
//unsigned long get_file_size(const char *file)
//{
//    FILE *fp;
//    long file_size;
//
//    if((fp=fopen(file, "rt")) == NULL)
//        return -1;
//
//	fseek(fp, 0, SEEK_END);
//	file_size = ftell(fp);
//	fclose(fp);
//
//	return file_size / 1024 * 1024;
//}


//****************patched by yagamishi add*************2016/02/05*******
//******************修改free的时候，换行符问题*****************************
unsigned long get_file_enter_num(const char *file)
{
  FILE *fp;
	char buf[1024];
	int enter_num=0;
  if((fp=fopen(file, "rt")) == NULL)
      return -1;
	while(fgets(buf,1024,fp) != NULL)
	{
		enter_num++;
	}
	fclose(fp);

	return (long)enter_num;
}
//*********************************************************************

/**
  * @brief  获取当前时间
  * @param  arg1：存储时间字符数组, arg2：时间格式
  * @retval 成功返回当前时间，失败返回NULL
  */
char *get_system_date(char *time_buf, int flag)
{
    time_t lt;
    struct tm *date_time;
    char fmt_time_buf[30] = {0};

    lt = time(NULL);
    date_time = localtime(&lt);
    strftime(fmt_time_buf, 30, "%x %X\n", date_time);

    if (flag == 0)
    {   ///年月日时分秒中间无点 20130703214724
        strcpy(time_buf, "20");
        strncat(time_buf, fmt_time_buf+6, 2);
        strncat(time_buf, fmt_time_buf, 2);
        strncat(time_buf, fmt_time_buf+3, 2);
        strncat(time_buf, fmt_time_buf+9, 2);
        strncat(time_buf, fmt_time_buf+12, 2);
        strncat(time_buf, fmt_time_buf+15, 2);
        return time_buf;
    }
    else
    {   ///年月日时分秒  2013/07/03 21:46:28
        strcpy(time_buf, "20");
        strncat(time_buf, fmt_time_buf+6, 2);
        strcat(time_buf, "-");
        strncat(time_buf, fmt_time_buf, 2);
        strcat(time_buf, "-");
        strncat(time_buf, fmt_time_buf+3, 2);
        strcat(time_buf, " ");
        strncat(time_buf, fmt_time_buf+9, 8);
        return time_buf;
    }
    return NULL;
}

/**
  * @brief  获取当前时间
  * @param  arg1：存储时间字符数组, arg2：时间格式
  * @retval 成功返回当前时间，失败返回NULL
  */
char *get_system_date2(char *time_buf, int flag)
{
    time_t lt;
    struct tm *date_time;
    char fmt_time_buf[30] = {0};

    lt = time(NULL);
    date_time = localtime(&lt);
    strftime(fmt_time_buf, 30, "%x %X\n", date_time);

    if (flag == 0)
    {   ///年月日时分秒中间无点 20130703214724
        strcpy(time_buf, "20");
        strncat(time_buf, fmt_time_buf+6, 2);
        strncat(time_buf, fmt_time_buf, 2);
        strncat(time_buf, fmt_time_buf+3, 2);
        strncat(time_buf, fmt_time_buf+9, 2);
        strncat(time_buf, fmt_time_buf+12, 2);
        strncat(time_buf, fmt_time_buf+15, 2);
        return time_buf;
    }
    else
    {   ///年月日时分秒  2013/07/03 21:46:28
        strcpy(time_buf, "20");
        strncat(time_buf, fmt_time_buf+6, 2);
        strcat(time_buf, "/");
        strncat(time_buf, fmt_time_buf, 2);
        strcat(time_buf, "/");
        strncat(time_buf, fmt_time_buf+3, 2);
        strcat(time_buf, " ");
        strncat(time_buf, fmt_time_buf+9, 8);
        return time_buf;
    }
    return NULL;
}

/**
  * @brief  获取10的多少次方
  * @param  arg1：指数
  * @retval 次方数
  */
int my_pow(int index)
{
    int i = 0;
    int sum = 1;
    for (i=0; i< index; i++)
        sum *= 10;
    return sum;
}


/**
  * @brief  字符串转换成整型
  * @param  arg1：字符串
  * @retval 整型数
  × @attention 注意字符串必须是包含0～9的数字(此处对非数字字符未做任何处理)
  */
int string_to_integer(const char *src)
{
    int i = 0;
    int sum = 0;
    int len = strlen(src);
    for (i=0; i<len; i++)
    {
        sum += (src[i]-48) * my_pow(len-i-1);
    }

    return sum;
}


/**
  * @brief  整型转换成字符串
  * @param  arg1：目标字符串 arg2：整数 arg3：浮点数 arg4：转换标记
  * @retval 目标字符串
  × @attention arg4中的标记，当转换的是整数时，标记为0; 当转换的是浮点数时,flag也标记浮点数的有效位数
  */
char *integer_to_string(char *dst, int value1, float value2, int flag)
{
    if (flag == 0)
    {
        sprintf(dst, "%d", value1);
        return dst;
    }
    else
    {
        sprintf(dst, "%f", value2);
        dst[flag+1] = '\0';
        return dst;
    }
    return NULL;
}


/**
  * @brief   版本号补齐
  * @param   arg1:补齐版本 arg2:原版本
  * @retval  返回补齐版本
  */
char *auto_complete_version(char *dst, const char *src)
{
    int   len        = 0;
    char *temp       = NULL;
    char *savep      = NULL;
    char  buffer[15] = {0};

    strcpy(buffer, src);

    temp = strtok_r(buffer, ".", &savep);
    while(temp != NULL)
    {
        len = strlen(temp);
        if (len == 1)
        {
            strcat(dst, "00");
            strcat(dst, temp);
        }
        else if (len ==2)
        {
            strcat(dst, "0");
            strcat(dst, temp);
        }
        else
        {
            strcat(dst, temp);
        }
        strcat(dst, ".");

        temp = strtok_r(NULL, ".", &savep);
    }

    dst[strlen(dst)-1] = '\0';
    return dst;
}


/**
  * @brief   获取子网掩码1的个数
  * @param   1：目标字符串  2：子网掩码
  * @retval  1的个数
  */
char *handler_subnet_mask(char * src, char *subnet_mask)
{
    int   cnt1       = 4;
    int   cnt2       = 0;
    int   value      = 0;
    char *temp       = NULL;
    char *savep      = NULL;
    char  buffer[16] = {0};

    strcpy(buffer, subnet_mask);
    temp = strtok_r(buffer, ".", &savep);

    while(temp != NULL)
    {
        cnt1--;
        if (strcmp(temp, "255") != 0)
        {
            value = atoi(temp);
            while (value % 2 == 0)
            {
                value >>= 1;
                if (cnt2 == 8)
                    break;
                cnt2++;
            }
            break;
        }
        temp = strtok_r(NULL, ".", &savep);
    }

    sprintf(src, "%d", 32-cnt2-cnt1*8);
    return src;
}

#ifdef ENABLE_SSL
/**
  * @brief     获取context的md5
  * @param     arg1 文件路径  arg2 flag为0获取32位md5值,否则为16位md5值
  * @retval    成功返回md5值,否则为NULL
  * @attention 此函数动态返回md5值,顾最终要调用free释放内存
  */
char *md5sum(const char *path, int flag)
{
#include <openssl/evp.h>
#define MD5_BUF_MAX_LEN  1024
//********************xiaohu****del******20170604**************
//    int             i;
//    int             len;
//    FILE           *fp;
//    char           *sum;
//    EVP_MD_CTX      mdctx;
//    unsigned char   buffer[MD5_BUF_MAX_LEN];
//
//    if ( (fp = fopen(path, "rb")) == NULL)
//        return NULL;
//
//    OpenSSL_add_all_algorithms();
//	EVP_MD_CTX_init(&mdctx);
//	EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL);
//    memset(buffer, 0, MD5_BUF_MAX_LEN);
//    while ( (len = fread(buffer, 1, MD5_BUF_MAX_LEN, fp)))
//    {
//        EVP_DigestUpdate(&mdctx, buffer, len);
//        memset(buffer, 0, MD5_BUF_MAX_LEN);
//    }
//    fclose(fp);
//
//	EVP_DigestFinal_ex(&mdctx, buffer, (unsigned int *)&len);
//	EVP_MD_CTX_cleanup(&mdctx);
//
//	sum = (char *)calloc(33, 1);
//	if (flag == 0)
//        for(i=0; i<len; i++)
//            sprintf(sum+i*2, "%02x", buffer[i]);
//	else
//        for(i=4; i<12; i++)
//            sprintf(sum+(i-4)*2, "%02x", buffer[i]);
//	return sum;
//********************xiaohu****del******20170604**************
return NULL;

}
#endif

/**
  * @brief     将点分十进制IP转换为无符号整型IP
  * @param     arg1 点分十进制IP
  * @retval    无符号整型IP
  */
unsigned int dotip_to_valip(const char *dotip)
{
    char           *split;
    char           *savep;
    char            dotipBak[16];
    unsigned int    intIp;
    unsigned char  *charIp;

    charIp = (unsigned char *)&intIp;
    strcpy(dotipBak, dotip);

    if ( (split = strtok_r(dotipBak, ".", &savep)) != NULL)
        charIp[0] = atoi(split);

    if ( (split = strtok_r(NULL, ".", &savep)) != NULL)
        charIp[1] = atoi(split);

    if ( (split = strtok_r(NULL, ".", &savep)) != NULL)
        charIp[2] = atoi(split);

    if ( (split = strtok_r(NULL, ".", &savep)) != NULL)
        charIp[3] = atoi(split);

    return intIp;
}

/**
  * @brief     将无符号整型IP转换为点分十进制IP
  * @param     arg1 存储点分十进制IP  arg2 无符号整型IP
  * @retval    valip
  */
char *valip_to_dotip(char *dotip, unsigned int valip)
{
    unsigned char *charIp;

    charIp = (unsigned char *)&valip;
    snprintf(dotip, 16, "%d.%d.%d.%d", charIp[0], charIp[1], charIp[2], charIp[3]);

    return dotip;
}



/******************* (C) COPYRIGHT 2020 上海今中网络科技有限公司 *****END OF FILE****/







